package com.cnoc.base.spring.config;

import java.util.Collection;

import java.util.Map;

import org.apache.log4j.Logger;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
 

@Component
public class ApplicationContextUtils implements ApplicationContextAware {

	private static Logger logger = Logger.getLogger(ApplicationContextUtils.class);
	private static final String DEFAULT_CONTEXT_XML = "classpath*:/cfg/spring/applicationContext.xml";
	private static ApplicationContext applicationContext = null;
	
	public ApplicationContextUtils() {
		// TODO Auto-generated constructor stub
	}
  

	 
	public static void initContext() {
		// TODO Auto-generated method stub
		initContext(DEFAULT_CONTEXT_XML);
	}

	 
	private static void initContext(String defaultContextXml) {
		// TODO Auto-generated method stub
		if(applicationContext == null){
			synchronized (ApplicationContextUtils.class) {
				if(applicationContext == null){
					logger.info("Spring tools init config location:"+ defaultContextXml);
					applicationContext = new ClassPathXmlApplicationContext(defaultContextXml);
					logger.info("Spring tools - factory success!");
				}
			}
		}
		  
	}
	
	public static Object getBeanByName(String beanName) {
		return applicationContext.getBean(beanName);
	}


	public static <T> Map<String, T> getBeansByClass(Class<T> c) {
		// org.apache.commons.dbcp.BasicDataSource.class
		return applicationContext.getBeansOfType(c);
	}

	public static <T> String[] getBeanNamesForType(Class<T> c) {
		// org.apache.commons.dbcp.BasicDataSource.class
		return applicationContext.getBeanNamesForType(c);
	}

	/**
	 * 判断spring容器中是否存在名字为beanName的bean
	 * @param beanName 
	 */
	public static boolean containsBean(String beanName){
		return applicationContext.containsBean(beanName);
	}
	
	public static <T> T getBean(String beanName, Class<T> type) {
		return applicationContext.getBean(beanName, type);
	}

	public static Object getBean(String beanName) {
		return getApplicationContext().getBean(beanName);
	}

	/**
	 * 根据类型获取bean
	 * @param type 
	 */
	public static <T> T getBean(Class<T> type) {
		return getApplicationContext().getBean(type);
	}

	/**
	 * 根据类型获取bean工厂中所有bean的Map集合
	 * @param type
	 * @return Map 
	 */
	public static <T> Map<String, T> getBeansMap(Class<T> type) {
		return getApplicationContext().getBeansOfType(type);
	}

	/**
	 * 
	 * @param type
	 * @return	Collection 
	 */
	public static <T> Collection<T> getBeans(Class<T> type) {
		Map<String, T> map = getBeansMap(type);
		if (map == null || map.size() == 0) {
			return null;
		} else {
			return map.values();
		}
	}

	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		// TODO Auto-generated method stub
		ApplicationContextUtils.applicationContext = applicationContext;
	}

	/**
	 * @return the beanFactory
	 */
	private  static ApplicationContext getApplicationContext() {
		return ApplicationContextUtils.applicationContext;
	}
	
	/**
	 * @return the beanFactory
	 */
	public  static DefaultListableBeanFactory getAutowireCapableBeanFactory() {
		
		return (DefaultListableBeanFactory)ApplicationContextUtils.applicationContext.getAutowireCapableBeanFactory();
	}
	
	public static void close() {
		((AbstractApplicationContext)ApplicationContextUtils.getApplicationContext()).close();
	}

}
